package com.simpou.commons.utils.behavior;

import com.simpou.commons.utils.lang.Conditionals;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.RequiredArgsConstructor;

/**
 * Grupo de condições.
 *
 * @param <T> Contexto.
 * @author Jonas Pereira
 * @since 2013-06-07
 * @version 2013-07-01
 */
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
public class Conditions<T> implements Iterable<Condition<T>>, Condition<T> {

    private final Set<Condition<T>> conditions;
    
    @Getter
    private Condition<T> lastFail;
    
    public Conditions() {
        this(new HashSet<Condition<T>>());
    }
    
    public boolean add(final Condition<T> condition) {
        if (condition == null) {
            return false;
        } else {
            return this.conditions.add(condition);
        }
    }

    @Override
    public Iterator<Condition<T>> iterator() {
        return conditions.iterator();
    }

    public void addAll(final List<? extends Condition<T>> conditionList) {
        this.conditions.addAll(conditionList);
    }

    public void addAll(final Conditions<T> conditions) {
        this.conditions.addAll(conditions.conditions);
    }

    public final Conditions<T> unmodifiable() {
        return new Conditions<T>(Collections.unmodifiableSet(conditions));
    }

    @Override
    public boolean check(final T context) {
        boolean result = true;
        lastFail = null;
        for (Condition<T> condition : conditions) {
            if (!condition.check(context)) {
                result = false;
                lastFail = condition;
                break;
            }
        }
        return result;
    }
}
